<template>
  <el-dialog
    :title="mode === 'edit' ? '修改备件' : '新增备件'"
    v-model="visibleInner"
    width="1200px"
    append-to-body
    @open="onOpen"
    class="fix-footer-dialog"
    :style="{ '--dlg-h': dialogHeight }"
  >
    <!-- 主信息 -->
    <el-form
      ref="formRef"
      :model="form"
      :rules="rules"
      label-width="90px"
      class="top-form"
    >
      <el-row :gutter="12">
        <el-col :span="6">
          <el-form-item label="备件编码" prop="code">
            <el-input
              v-model="form.code"
              :disabled="mode === 'edit' && lockCodeOnEdit"
              placeholder="唯一，必填, 大写字母)"
              maxlength="64"
              @input="onCodeInput" 
              inputmode="latin"
            />
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item label="备件名称" prop="name">
            <el-input v-model="form.name" placeholder="备件名称" />
          </el-form-item>
        </el-col>

        <!-- <el-col :span="6">
          <el-form-item label="备件单位" prop="unit">
            <el-select v-model="form.unit" style="width: 100%">
              <el-option
                v-for="u in unitOptionsInner"
                :key="u.value"
                :label="u.label"
                :value="u.value"
              />
            </el-select>
          </el-form-item>
        </el-col> -->

        <el-col :span="6">
          <el-form-item label="备件类型" prop="type">
            <el-select v-model="form.type" style="width: 100%">
              <el-option
                v-for="t in typeOptionsInner"
                :key="t.value"
                :label="t.label"
                :value="t.value"
              />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item label="备件状态" prop="status">
            <el-select v-model="form.status" style="width: 100%">
              <el-option
                v-for="s in statusOptionsInner"
                :key="s.value"
                :label="s.label"
                :value="s.value"
              />
            </el-select>
          </el-form-item>
        </el-col>

        <el-col :span="6">
          <el-form-item label="最低库存" prop="minStock">
            <el-input-number
              v-model="form.minStock"
              :min="0"
              :precision="0"
              :step="1"
              controls-position="right"
              style="width: 100%"
            />
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item label="最高库存" prop="maxStock">
            <el-input-number
              v-model="form.maxStock"
              :min="0"
              :precision="0"
              :step="1"
              controls-position="right"
              style="width: 100%"
            />
          </el-form-item>
        </el-col> 
        <el-col :span="6">
          <el-form-item label="总库存" prop="stockTotal">
            <el-input-number
              v-model="form.stockTotal"
              :min="0"
              :precision="0"
              :step="1"
              controls-position="right"
              style="width: 100%"
            />
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item label="当前库存" prop="stockAvailable">
            <el-input-number
              v-model="form.stockAvailable"
              :min="0"
              :precision="0"
              :step="1"
              controls-position="right"
              style="width: 100%"
            />
          </el-form-item>
        </el-col>
        <!-- <el-col :span="6">
          <el-form-item label="已用数量">
            <el-input :model-value="usedCount" disabled />
          </el-form-item>
        </el-col> -->

        <!-- <el-col :span="6">
          <el-form-item label="计划日期">
            <el-date-picker
              v-model="form.planDate"
              type="date"
              value-format="YYYY-MM-DD"
              placeholder="选择日期"
              style="width: 100%"
            />
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item label="采购周期">
            <el-input-number
              v-model="form.orderDate"
              :min="0"
              :precision="0"
              :step="1"
              controls-position="right"
              style="width: 100%"
              placeholder="单位：天"
            />
          </el-form-item>
        </el-col> -->

        <el-col :span="24">
          <el-form-item label="备注说明">
            <el-input
              v-model="form.remark"
              type="textarea"
              :rows="2"
              placeholder="备注说明"
            />
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>

    <!-- 规格/厂商列表 -->
    <div class="variants-toolbar">
      <el-button type="primary" plain @click="addVariant()">新增规格</el-button>
      <el-button
        type="success"
        plain
        :disabled="!variants.length"
        @click="copyVariant(variants.at(-1), variants.length - 1)"
        >复制最后一行</el-button
      >
      <el-text type="info"
        >同一编码下可维护多条规格/厂商；空行将自动忽略；规格+厂商去重。</el-text
      >
    </div>

    <el-table :data="variants" border stripe size="small" :height="360">      
      <el-table-column label="厂商名称" min-width="200" >
        <template #default="{ row }">
          <el-input v-model="row.vendor" placeholder="供应商" />
        </template>
      </el-table-column>
      <el-table-column label="规格名称" min-width="200"  >
        <template #default="{ row }">
          <el-input v-model="row.spec" placeholder="如 6204-2RS / DN50×DN65" />
        </template>
      </el-table-column>
      <!-- <el-table-column label="状态" width="120">
        <template #default="{ row }">
          <el-select v-model="row.status" style="width: 100%">
            <el-option
              v-for="s in statusOptionsInner"
              :key="s.value"
              :label="s.label"
              :value="s.value"
            />
          </el-select>
        </template>
      </el-table-column> -->
      <el-table-column label="操作" width="150" fixed="right" align="center">
        <template #default="{ row, $index }">
          <el-button link type="primary" @click="copyVariant(row, $index)"
            >复制</el-button
          >
          <el-button link type="danger" @click="removeVariant($index)"
            >删除</el-button
          >
        </template>
      </el-table-column>
    </el-table>

    <template #footer>
      <div class="dialog-footer">
        <el-button @click="close">取 消</el-button>
        <el-button type="primary" :loading="submitting" @click="submit"
          >确 定</el-button
        >
      </div>
    </template>
  </el-dialog>
</template>

<script setup>
import { ref, reactive, computed, watch } from "vue";
import { ElMessage } from "element-plus";

/** Props */
const props = defineProps({
  /** v-model:visible */
  visible: { type: Boolean, default: false },
  /** 'add' | 'edit' */
  mode: { type: String, default: "add" },
  /** 编辑时是否锁定编码（一般建议锁定，避免唯一键冲突） */
  lockCodeOnEdit: { type: Boolean, default: true },
  /** 初始值（编辑时传入后端查询结果；新增可为空） */
  model: { type: Object, default: () => ({}) },

  /** 选项（可复用时覆盖） */
  unitOptions: {
    type: Array,
    default: () =>
      ["个", "台", "套", "米", "公斤"].map((v) => ({ label: v, value: v })),
  },
  statusOptions: {
    type: Array,
    default: () => [
      { label: "启用", value: 0 },
      { label: "停用", value: 1 },
    ],
  },
  typeOptions: {
    type: Array,
    default: () => [
      { label: "普通", value: 0 },
      { label: "特殊备件", value: 1 },
    ],
  },

  /** 外部loading（发请求时父组件控制） */
  submitting: { type: Boolean, default: false },
  dialogHeight: { type: String, default: "82vh" },
});

/** Emits */
const emit = defineEmits(["update:visible", "submit", "open"]);

/** v-model 代理 */
const visibleInner = computed({
  get: () => props.visible,
  set: (v) => emit("update:visible", v),
});

/** 选项代理 */
const unitOptionsInner = computed(() => props.unitOptions);
const statusOptionsInner = computed(() => props.statusOptions);
const typeOptionsInner = computed(() => props.typeOptions);

/** 主表单 & 校验 */
const formRef = ref();
const form = reactive({
  id: null,
  code: "",
  name: "",
  unit: "个",
  minStock: 10,
  maxStock: 30,
  stockTotal: 0,
  stockAvailable: 0,
  type: 0,
  status: 0,
  planDate: null,
  orderDate: 0,
  remark: "",
});

// 放在 rules 上方
function onCodeInput(val) {
  const s = (val || "").toUpperCase().replace(/[^A-Z0-9\-_]/g, "");
  if (s !== form.code) form.code = s;
}
 

// ✅ 函数声明会提升
function validateCode(_r, v, cb) {
  const s = (v || "").trim();
  if (!s) return cb(new Error("编码必填"));
  if (!/^[A-Z0-9\-_]+$/.test(s))
    return cb(new Error("编码仅可包含英文字母/数字/“-”/“_”，且不能含中文"));
  cb();
}

function validateNonNegInt(name) {
  return (_r, v, cb) => {
    const n = Number(v);
    if (!Number.isInteger(n) || n < 0)
      return cb(new Error(`${name}需为≥0的整数`));
    cb();
  };
}

const rules = {
  code: [
    { required: true, message: "编码必填", trigger: "blur" },
    { validator: validateCode, trigger: ["blur", "change"] },
  ],
  name: [{ required: true, message: "名称必填", trigger: "blur" }],
  unit: [{ required: true, message: "单位必选", trigger: "change" }],
  vendor: [{ required: true, message: "厂商不能为空", trigger: "blur" }],
  spec: [{ required: true, message: "规格不能为空", trigger: "blur" }],
  stockTotal: [
    { validator: validateNonNegInt("总库存"), trigger: ["blur", "change"] },
  ],
  stockAvailable: [
    { validator: validateNonNegInt("当前库存"), trigger: ["blur", "change"] },
  ],
  orderDate: [
    { validator: validateNonNegInt("采购周期"), trigger: ["blur", "change"] },
  ],
};

/** 规格列表 */
const variants = ref([]);

const usedCount = computed(
  () => Number(form.stockTotal || 0) - Number(form.stockAvailable || 0)
);

/** 打开时填充 */
function onOpen() {
  // 主表单
  const m = props.model || {};
  form.id = m.id ?? null;
  form.code = m.code ?? "";
  form.name = m.name ?? "";
  form.unit = m.unit ?? (unitOptionsInner.value?.[0]?.value || "个");
  form.stockTotal = Number(m.stockTotal ?? 0);
  form.stockAvailable = Number(m.stockAvailable ?? 0);
  form.type = Number(m.type ?? 0);
  form.status = Number(m.status ?? 0);
  form.planDate = m.planDate ?? null;
  form.orderDate = Number(m.orderDate ?? 0);
  form.remark = m.remark ?? "";

  // 规格
  variants.value = normalizeVariants(m.variants || []);
  if (!variants.value.length) addVariant();

  emit("open");
}

function normalizeVariants(list) {
  return (list || []).map((v) => ({
    id: v.id ?? null,
    spec: (v.spec ?? "").trim(),
    vendor: (v.vendor ?? "").trim(),
    status: Number(v.status ?? 0),
  }));
}

/** 规格操作 */
function newVariant() {
  return { id: null, spec: "", vendor: "", status: 0 };
}
function addVariant(afterIndex) {
  if (typeof afterIndex === "number")
    variants.value.splice(afterIndex + 1, 0, newVariant());
  else variants.value.push(newVariant());
}
function copyVariant(row, index) {
  const c = JSON.parse(JSON.stringify(row || newVariant()));
  c.id = c.id || null; // 复制时不要带旧的 id
  variants.value.splice((index ?? variants.value.length - 1) + 1, 0, c);
}
function removeVariant(index) {
  variants.value.splice(index, 1);
  if (!variants.value.length) addVariant();
}

/** 提交 */
function submit() {
  formRef.value.validate((ok) => {
    if (!ok) return;

    // ✅ 基础校验
    if (!/^[A-Z0-9\-_]+$/.test(form.code || "")) {
      return ElMessage.warning("编码仅可包含英文字母/数字/“-”/“_”");
    }
    if (form.stockAvailable > form.stockTotal) {
      return ElMessage.warning("当前库存不可大于总库存");
    }

    // ✅ 校验规格/厂商
    const seen = new Set();
    const out = [];

    // 如果 variants 为空或全部空行，直接不允许提交
    if (!variants.value.length || variants.value.every(v => !v.spec && !v.vendor)) {
      return ElMessage.error("请至少填写一条规格和厂商信息");
    }

    for (const [i, v] of variants.value.entries()) {
      const spec = (v.spec || "").trim();
      const vendor = (v.vendor || "").trim();

      // 若行中任一字段缺失，则报错并阻止提交
      if (!spec || !vendor) {
        return ElMessage.error(`第 ${i + 1} 行：厂商和规格均不能为空`);
      }

      const key = `${spec}@@${vendor}`;
      if (seen.has(key)) continue; // 去重
      seen.add(key);

      out.push({
        id: v.id || null,
        spec,
        vendor,
        status: Number(v.status || 0),
      });
    }

    // ✅ 通过所有校验后构造 payload
    const payload = {
      id: form.id,
      code: (form.code || "").trim(),
      name: (form.name || "").trim(),
      unit: form.unit || "个",
      stockTotal: Number(form.stockTotal) || 0,
      stockAvailable: Number(form.stockAvailable) || 0,
      minStock: Number(form.minStock) || 0,
      maxStock: Number(form.maxStock) || 0,
      isSpecial: Number(form.isSpecial) || 0,
      status: Number(form.status) || 0,
      remark: (form.remark || "").trim(),
      planDate: form.planDate || null,
      orderDate: Number.parseInt(form.orderDate) || 0,
      variants: out,
    };

    emit("submit", payload);
  });
}


function close() {
  visibleInner.value = false;
}

defineExpose({ open: () => (visibleInner.value = true), close });
</script>

<style scoped>
.top-form :deep(.el-form-item) {
  margin-bottom: 12px;
}
.variants-toolbar {
  display: flex;
  gap: 8px;
  align-items: center;
  margin: 8px 0 10px;
}

/* ===== 关键：固定底部按钮，内容区滚动 ===== */
:deep(.fix-footer-dialog) {
  display: flex;
  flex-direction: column;
  height: var(--dlg-h, 82vh); /* 整体高度，可被 :style 覆盖 */
  max-height: var(--dlg-h, 82vh);
}

/* 让 body 占满剩余空间并滚动 */
:deep(.fix-footer-dialog .el-dialog__body) {
  flex: 1;
  overflow: auto;
  padding: 12px 20px 16px;
}

/* 页脚固定在底部且不被内容遮住 */
:deep(.fix-footer-dialog .el-dialog__footer) {
  position: sticky;
  bottom: 0;
  z-index: 2;
  background: var(--el-bg-color); /* 与主题统一 */
  border-top: 1px solid var(--el-border-color);
  padding: 10px 16px;
}

/* 可选：当 body 里表格很多时，给内层再加点底部留白，避免视觉拥挤 */
:deep(.fix-footer-dialog .el-dialog__body .el-table) {
  margin-bottom: 4px;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end; /* 让按钮靠右 */
  gap: 8px;
}

.top-form :deep(.el-form-item) {
  margin-bottom: 20px !important;
  overflow: visible !important;
}
:deep(.el-form-item__error) {
  position: absolute !important;
  bottom: -18px !important;
  white-space: nowrap;
  z-index: 20;
}

</style>
